﻿using System;

using Microsoft.Practices.ServiceLocation;

namespace Moq.Contrib.Indy
{
	/// <summary>
	/// Interface implemented by the <see cref="AutoMockContainer"/> so that 
	/// the various method overloads can receive a creation 
	/// function for the service, rather than just a type.
	/// </summary>
	public interface IMockContainer
	{
		/// <summary>
		/// Resolves a required service of the given type.
		/// </summary>
		T Resolve<T>();

		/// <summary>
		/// Gets or creates a mock for the given type, with 
		/// the default behavior specified by the factory.
		/// </summary>
		Mock<T> GetMock<T>() where T : class;

		/// <summary>
		/// Creates an instance of a class under test, 
		/// injecting all necessary dependencies as mocks.
		/// </summary>
		/// <typeparam name="T">Requested object type.</typeparam>
		T Create<T>();

		/// <summary>
		/// Creates an instance of a class under test using 
		/// the given activator function.
		/// </summary>
		/// <typeparam name="T">Requested object type.</typeparam>
		T Create<T>(Func<IMockContainer, T> activator);

		/// <summary>
		/// Registers the given service on the container.
		/// </summary>
		/// <typeparam name="TService">Service</typeparam>
		/// <typeparam name="TImplementation">The implementation of the service.</typeparam>
		void Register<TService, TImplementation>();

		/// <summary>
		/// Registers the given service instance on the container.
		/// </summary>
		/// <typeparam name="TService">Service type.</typeparam>
		/// <param name="instance">Service instance.</param>
		void Register<TService>(TService instance) where TService : class;

		/// <summary>
		/// Registers the given service creation delegate on the container.
		/// </summary>
		/// <typeparam name="TService">Service type.</typeparam>
		void Register<TService>(Func<IMockContainer, TService> activator);

		/// <summary>
		/// Gets the locator.
		/// </summary>
		IServiceLocator Locator { get; }
	}
}